package framework.model;

import java.util.Iterator;
import java.util.ArrayList;

public class SelectiveList<T, R> extends ArrayList<T> {
    
    public void doAll(IFunctor<T> f) {
        Iterator<T> it = this.iterator();
        while(it.hasNext()) {
            f.compute(it.next());
        }
    }
    
    public Iterator iterator(IPredicate<T> p) {
        return new SelectiveIterator(this.iterator(), p);
    }
    
    public void doAll(IFunctor<T> f, IPredicate<T> p) {
        Iterator<T> it = this.iterator();
        while(it.hasNext()) {
            T v = it.next();
            if(p.check(v)) {
                f.compute(v);
            }
        }
    }
    // using Selective Iterator
    public void forAll(IFunctor<T> f, IPredicate<T> p) {
        Iterator<T> it = new SelectiveIterator(this.iterator(), p);
        while(it.hasNext()) {
            f.compute(it.next());
        }
    }    

    public void doAll(IFunctor f, IPredicate p1, IPredicate p2) {
        Iterator<T> it1 = new SelectiveIterator(this.iterator(), p1);
        Iterator<T> it2 = new SelectiveIterator(it1, p2);
        while (it2.hasNext()) {
            f.compute(it2.next());
        }
    }
   // using filter with View
    public View<T> filter(IPredicate<T> p) {
        return new View(this, p);
    }    
   // Deal with generic return value 
//   public <R> R forAll(IFunctor<T, R> f) {        
//        for (T item : this) {
//            f.compute(item);
//        }
//        return f.getValue();
//    }
}